package org.yu.team2023.flashdays.registries;

import lombok.RequiredArgsConstructor;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.block.Block;
import net.minecraftforge.client.model.generators.ModelFile;
import net.minecraftforge.common.util.NonNullFunction;
import net.minecraftforge.fml.loading.FMLLoader;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
import org.jetbrains.annotations.NotNull;

import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;

@RequiredArgsConstructor
public class ItemBuilder<T extends Item,B> {
    private final SimpleReg context;
    private final String id;
    private final NonNullFunction<Item.Properties,T> factory;
    private final B parent;
    private Item.Properties properties;
    private Supplier<CreativeModeTab> tab;
    private String langCN;
    public ItemBuilder<T,B> properties(Item.Properties properties){
        this.properties=properties;
        return this;
    }
    public ItemBuilder<T,B> tab(Supplier<CreativeModeTab> tab){
        this.tab=tab;
        return this;
    }
    public ItemBuilder<T,B> model(BiConsumer<Supplier<? extends ItemLike>,SimpleItemModelProvider> consumer){
        if(!FMLLoader.isProduction()){
            context.itemModels.put(()-> ForgeRegistries.ITEMS.getValue(new ResourceLocation(context.id,id)),consumer);
        }
        return this;
    }
    public ItemBuilder<T,B> simpleModel(){
        return this.model((supplier, simpleItemModelProvider) -> simpleItemModelProvider.basicItem(supplier.get().asItem()));
    }
    public ItemBuilder<T,B> copyModel(Supplier<? extends Item> item){
        return this.model((supplier, provider) -> {
            var thisKey=ForgeRegistries.ITEMS.getKey(supplier.get().asItem());
            var key=ForgeRegistries.ITEMS.getKey(item.get());
            provider.getBuilder(thisKey.toString())
                    .parent(new ModelFile.UncheckedModelFile(new ResourceLocation(key.getNamespace(),"item/"+key.getPath())));
        });
    }
    public ItemBuilder<T,B> copyBlockModel(Supplier<? extends Block> block){
        return this.model((supplier, provider) -> {
            var thisKey=ForgeRegistries.ITEMS.getKey(supplier.get().asItem());
            var key=ForgeRegistries.BLOCKS.getKey(block.get());
            provider.getBuilder(thisKey.toString())
                    .parent(new ModelFile.UncheckedModelFile(new ResourceLocation(key.getNamespace(),"block/"+key.getPath())));
        });
    }
    @SuppressWarnings("unchecked")
    public B popParent(@NotNull TagKey<Item>... tagKeys){
        build(tagKeys);
        return parent;
    }
    public ItemBuilder<T,B> lang(String value){
        langCN=value;
        return this;
    }
    @SafeVarargs
    public final RegistryObject<T> build(@NotNull TagKey<Item>... tagKeys){
        if(properties==null)properties=new Item.Properties();
        RegistryObject<T> result=context.itemDeferredRegister.register(id,()->factory.apply(properties));
        if(tab==null)tab=context.modTab;
        if(tab!=null)
            context.creativeTabMap.put(tab,result);
        if(tagKeys.length>0)
            context.addItemTag(result,tagKeys);
        if(langCN!=null)
            context.langCH.put(()->result.get().getDescriptionId(),langCN);
        return result;
    }

}
